package com.codi.api.controller;

import com.codi.api.security.UserUtil;
import com.codi.api.validation.AccountValidation;
import com.codi.base.log.annotation.Loggable;
import com.codi.base.util.DateUtils;
import com.codi.base.util.ListUtil;
import com.codi.base.util.MD5;
import com.codi.base.util.StringUtil;
import com.codi.base.web.ResponseUtils;
import com.codi.bus.constant.GlobalConstant;
import com.codi.bus.core.domain.BankLimit;
import com.codi.bus.core.domain.User;
import com.codi.bus.core.domain.UserBank;
import com.codi.bus.core.fund.FundErrorConst;
import com.codi.bus.core.resultModel.*;
import com.codi.bus.core.service.BankLimitService;
import com.codi.bus.core.service.BankService;
import com.codi.bus.core.service.QueryService;
import com.codi.bus.core.service.UserService;
import com.codi.bus.core.service.model.ApplyModel;
import com.codi.bus.core.service.model.BankModel;
import com.codi.bus.core.service.model.ShareModel;
import com.codi.bus.core.service.util.HundsunUtils;
import com.codi.bus.core.service.util.ModelPopulateUtils;
import com.codi.bus.core.vo.UserProfileVo;
import com.codi.bus.exception.BaseException;
import com.codi.fcloud.ufx.HsResponseUtil;
import com.codi.message.constant.ErrorConstant;
import com.codi.message.util.MessageUtil;
import com.codi.trade.service.LoginAcctService;
import com.codi.trade.service.ShareQueryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;

@Controller
@RequestMapping("/bank")
public class BankController {

    private static final Logger logger = LoggerFactory.getLogger(BankController.class);

    @Resource(name = "bankService")
    private BankService bankService;

    @Resource(name = "userService")
    private UserService userService;

    @Resource(name = "queryService")
    private QueryService queryService;

    @Resource(name = "loginAcctService")
    private LoginAcctService loginAcctService;

    @Autowired
    private AccountValidation accountValidation;

    @Autowired
    private BankLimitService bankLimitService;

    /**
     * 点击下一步, 检查银行卡是否处在开户状态
     */
    @GetMapping("checkBankAccountStatus")
    public void checkBankStatus(HttpServletRequest request, HttpServletResponse response, String bankAccount) {
        BaseResult result = new BaseResult();

        if (StringUtil.isEmpty(bankAccount)) {
            result.setSuccess(false);
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            Map<String, String> map = new HashMap<>();
            map.put(ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "银行卡号");
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND, map));

            ResponseUtils.renderJson(request, response, result, true);

            return;
        }

        Long userId = UserUtil.getLoginUserId();
//        UserBank userBank = bankService.getByBankNo(userId, bankAccount.trim());

        List<UserBank> userBanks = bankService.getBanks(userId, bankAccount.trim());

        UserBank userBank = null;

        if (userBanks != null) {
            for (UserBank bank : userBanks) {
                if (! "1".equals(bank.getCapitalMode())) {
                    userBank = bank;

                    break;
                }
            }
        }

        result.setResult(userBank);

        ResponseUtils.renderJson(request, response, result, true);
    }

    /**
     * 启用银行卡
     */
    @PostMapping("activeBankAccount")
    public void activeBankAccount(HttpServletRequest request, HttpServletResponse response, String bankAccount) {
        BaseResult result = new BaseResult();

        if (StringUtil.isEmpty(bankAccount)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            Map<String, String> map = new HashMap<>();
            map.put(ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "银行卡号");
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND, map));
            result.setSuccess(false);

            ResponseUtils.renderJson(request, response, result, true);

            return;
        }

        Long userId = UserUtil.getLoginUserId();

        List<UserBank> userBanks = bankService.getBanks(userId, bankAccount.trim());

        if (userBanks != null) {
            for (UserBank bank : userBanks) {
                if (! GlobalConstant.CAPITAL_MODE_COUNTER.equals(bank.getCapitalMode())) {
                    bank.setBankState("1");

                    bankService.updateByPrimaryKey(bank);
                }
            }
        }

        if (userBanks == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorConstant.ERROR_NO_BANK_CARD_FIND);
            result.setErrorMessage(MessageUtil.getErrorMsg(ErrorConstant.ERROR_NO_BANK_CARD_FIND));

            ResponseUtils.renderJson(request, response, result, true);

            return;
        }

        ResponseUtils.renderJson(request, response, result, true);
    }

    /**
     * 检查银行卡数量
     * @param request
     * @param response
     */
    @GetMapping("checkBankCardCounts")
    public void checkBankCardCounts(HttpServletRequest request, HttpServletResponse response) {
        Long userId = UserUtil.getLoginUserId();
        List<UserBank> banks = bankService.getBankCardsNotInCounter(userId);
        BaseResult result = new BaseResult();

        if (banks != null) {
            if (banks.size() >= 5) {
                result.setSuccess(false);
                result.setErrorType(GlobalConstant.ERROR_TYPE_APPLICATION);
                result.setErrorCode(ErrorConstant.ERROR_BANK_COUNTS_MAX);
                result.setErrorMessage(MessageUtil.getErrorMsg(ErrorConstant.ERROR_BANK_COUNTS_MAX));
            }
        }

        ResponseUtils.renderJson(request, response, result, true);
    }

    @PostMapping("/add_bank")
    @Loggable
    public void addBank(@RequestParam String userName, @RequestParam String userCard, @RequestParam String tradePassword,
                        @RequestParam String bankCode, @RequestParam String bankName, @RequestParam String userBankNo,
                        @RequestParam String userBankMobile, @RequestParam String originalSerialNo,
                        @RequestParam String smsSerialNo, @RequestParam String mobileCode, @RequestParam String vcBranchbank,
                        @RequestParam boolean isOpen,@RequestParam String vcBankname,
                        HttpServletRequest request, HttpServletResponse response) {
        AccountOpenResult result = null;

        Long userId = UserUtil.getLoginUserId();
        // 用户基本信息
        User entity = new User();
        entity.setUserId(userId);
        entity.setUserName(userName);
        entity.setUserCard(userCard);
        entity.setTradePassword(tradePassword);
        // 银行卡信息
        UserBank bankEntity = new UserBank();
        bankEntity.setBankCode(bankCode);
        bankEntity.setBankName(bankName);
        bankEntity.setUserBankNo(userBankNo);
        bankEntity.setBranchbank(vcBranchbank);
        bankEntity.setBankBranchName(vcBankname);
        logger.info("开户v3 联行号：{}，支行名称：{}",bankEntity.getBranchbank(),bankEntity.getBankBranchName());
        bankEntity.setUserBankMobile(userBankMobile);
        bankEntity.setUserId(userId);
        bankEntity.setUserBankOwner(userName);
        bankEntity.setCapitalMode(GlobalConstant.CAPITAL_MODE_EPAY);

        // 验证输入
        PaySignResult payResult = null;

        payResult = accountValidation.validateBankAddAccount(entity, bankEntity, originalSerialNo, smsSerialNo, mobileCode,
            isOpen);

        if (payResult != null) {
            ResponseUtils.renderJson(request, response, result, true);

            return;
        }

        //验证支行信息
        BaseResult baseResult = null;
        baseResult = accountValidation.validateBranch(bankEntity.getBranchbank());
        if (baseResult != null) {
            ResponseUtils.renderJson(request, response, baseResult, true);

            return;
        }

        // Step 1: 调用实名验证步骤二接口
        // 身份证转成大写
        entity.setUserCard(entity.getUserCard().toUpperCase());
        payResult = userService.paySign_Step_Two(entity, bankEntity, originalSerialNo, smsSerialNo, mobileCode);

        if (payResult.getSuccess() == false) {

            if (StringUtil.isEmpty(payResult.getErrorMessage())) {
                payResult.setErrorMessage(MessageUtil.getErrorMessage(payResult.getErrorCode(), null));
            }

            ResponseUtils.renderJson(request, response, payResult, true);

            return;
        }

        // Step 2: 调用新增交易账号
        // 完成银行卡绑定
        result = userService.addAccount(userId, userCard, tradePassword, userName, bankCode, userBankNo, bankName,
            userBankMobile, GlobalConstant.CAPITAL_MODE_EPAY, payResult.getProtocolNo(), vcBranchbank, vcBankname);
        if (result.getSuccess() == false) {
            if (StringUtil.isEmpty(result.getErrorMessage())) {
                result.setErrorMessage(MessageUtil.getErrorMessage(result.getErrorCode(), null));
            }

            ResponseUtils.renderJson(request, response, result, true);

            return;
        }

        ResponseUtils.renderJson(request, response, result, true);
    }

    @PostMapping("/unbind_bank_sure")
    public void unbindBankSure(String bankAccount, HttpServletRequest request, HttpServletResponse response, String tradePassword, String capitalMode) {
        Long userId = UserUtil.getLoginUserId();
        User user = userService.getUser(userId);

        BaseResult result = new BaseResult();


        tradePassword = MD5.MD5Encode(tradePassword.trim());

        Map<String, Object> map = loginAcctService.login(tradePassword, user.getUserName(), user.getUserCard());

        // 查询结果
        List<Map<String, Object>> list = new ArrayList<>();

        if (!HsResponseUtil.isOperationOk(map)) {
            result.setSuccess(false);
            result.setErrorCode(FundErrorConst.TRADE_PWD_WRONG);
            result.setErrorMessage(MessageUtil.getErrorMsg(FundErrorConst.TRADE_PWD_WRONG));

            ResponseUtils.renderJson(request, response, result, true);

            return;
        }

        //执行解绑操作

        List<UserBank> userBanks = bankService.getBanks(userId, bankAccount);

        if (userBanks != null) {
            for (UserBank bank : userBanks) {
                if (bank.getCapitalMode().equals(capitalMode)) {
                    //设置银行卡状态 注销
                    bank.setBankState("0");
//                    bank.setCapitalMode(capitalMode);
                    bankService.updateByPrimaryKey(bank);
                }
            }
        }

        ResponseUtils.renderJson(request, response, result, true);
    }

    @PostMapping("/unbind_bank")
    @Loggable
    public void unbindBank(String bankAccount, HttpServletRequest request, HttpServletResponse response, String capitalMode) {
        Long userId = UserUtil.getLoginUserId();

        ResponseUtils.renderJson(request, response, queryService.checkSharesExistByBankAccount(userId, bankAccount, capitalMode), true);
    }

    @RequestMapping(value = "/get", method = RequestMethod.GET)
    @Loggable
    public void getBanks(HttpServletRequest request, HttpServletResponse response, @RequestParam String token,
                         @RequestHeader(value = GlobalConstant.HEADER_APP_DEVICE) String deviceId) {
        BaseListResult result = null;


        // 获取客户编号
        User userEntity = userService.getUser(UserUtil.getLoginUserId());
        if (userEntity == null) {
            result = new BankListResult();
            result.setSuccess(false);
            result.setErrorCode(ErrorConstant.ERROR_NO_USER_FIND);
            ResponseUtils.renderJson(request, response, result, true);
            return;
        }
        if (StringUtil.isEmpty(userEntity.getExternalClientId())) {
            result = new BankListResult();
            result.setSuccess(true);
        } else {

            //2017-12-28 14:34:26 spy disable
            // 调用恒生接口获取银行卡
//			result = queryService.queryAccountBanks("", userEntity.getExternalClientId(), "",
//					GlobalConstant.MAX_REQUEST_NUM, 1, 1, "1");
//			if (result.getSuccess() == false && StringUtil.isEmpty(result.getErrorMessage())) {
//				result.setErrorMessage(MessageUtil.getErrorMessage(result.getErrorCode(), null));
//			}


            List<UserBank> userBanks = bankService.getListByUserId(UserUtil.getLoginUserId());

            if (ListUtil.isNotEmpty(userBanks)) {
                result = new BankListResult();
                result.setSuccess(true);

                List<BankModel> banks = new ArrayList<>(userBanks.size());
                userBanks.forEach(bank -> {
                    BankModel bankModel = new BankModel();
                    bankModel.setBranchBank(bank.getBranchbank() == null ? "": bank.getBranchbank());
                    bankModel.setBranchBankName(bank.getBankBranchName() == null ? "": bank.getBankBranchName());
                    bankModel.setBankName(bank.getBankName());
                    bankModel.setBankCode(bank.getBankCode());
                    bankModel.setUserBankNo(bank.getUserBankNo());
                    bankModel.setCapitalMode(bank.getCapitalMode());
                    bankModel.setTradeAccount(bank.getExternalTradeAccount());


                    banks.add(bankModel);
                });

                ((BankListResult) result).setBanks(banks);
            }
        }

        ResponseUtils.renderJson(request, response, result, true);

    }

    @RequestMapping(value = "/getApp", method = RequestMethod.GET)
    @Loggable
    public void getAppBanks(HttpServletRequest request, HttpServletResponse response) {
        BaseListResult result = null;

        // 获取客户编号
        User userEntity = userService.getUser(UserUtil.getLoginUserId());
        if (userEntity == null) {
            result.setSuccess(false);
            result = new BankListResult();
            result.setErrorCode(ErrorConstant.ERROR_NO_USER_FIND);
            ResponseUtils.renderJson(request, response, result, true);
            return;
        }
        if (StringUtil.isEmpty(userEntity.getExternalClientId())) {
            result = new BankListResult();
            result.setSuccess(true);
        } else {

            List<UserBank> userBanks = bankService.getListByUserId(UserUtil.getLoginUserId());

            if (ListUtil.isNotEmpty(userBanks)) {
                result = new BankListResult();
                result.setSuccess(true);

                List<BankModel> banks = new ArrayList<>(userBanks.size());
                for (UserBank bank : userBanks){
                    if (GlobalConstant.CAPITAL_MODE_COUNTER.equals(bank.getCapitalMode())){
                        continue;
                    }
                    BankModel bankModel = new BankModel();
                    bankModel.setBranchBank(bank.getBranchbank() == null ? "": bank.getBranchbank());
                    bankModel.setBranchBankName(bank.getBankBranchName() == null ? "": bank.getBankBranchName());
                    bankModel.setBankName(bank.getBankName());
                    bankModel.setBankCode(bank.getBankCode());
                    bankModel.setUserBankNo(bank.getUserBankNo());
                    bankModel.setCapitalMode(bank.getCapitalMode());
                    bankModel.setTradeAccount(bank.getExternalTradeAccount());
                    //查询该银行的限额
                    BankLimit bankLimit = bankLimitService.selectByCodeAndChannel(bank.getBankCode(), bank.getCapitalMode());
                    if (bankLimit != null) {

                        // 单笔限额max
                        if (bankLimit.getSingleLimit() == null || bankLimit.getSingleLimit() == -1) {
                        } else {
                            bankModel.setSingleDealMaxValue(BigDecimal.valueOf(bankLimit.getSingleLimit()));
                        }
                    }
                    banks.add(bankModel);
                }


                ((BankListResult) result).setBanks(banks);
            }
        }

        ResponseUtils.renderJson(request, response, result, true);

    }

    @RequestMapping(value = "pay-banks", method = RequestMethod.GET)
    public void getPayBanks(HttpServletRequest request, HttpServletResponse response, @RequestParam String token,
                            @RequestParam String capitalMode,
                            @RequestHeader(value = GlobalConstant.HEADER_APP_DEVICE) String deviceId) {
        logger.info("Receive pay-bakns request, capitalMode:" + capitalMode);
        PayableBankListResult result = null;
        // 验证token
        ValidateTokenResult validateTokenResult = userService.validateToken(token, deviceId);
        if (!validateTokenResult.getSuccess()) {
            String errorMessage = MessageUtil.getErrorMessage(validateTokenResult.getErrorCode(), null);
            validateTokenResult.setErrorMessage(errorMessage);
            ResponseUtils.renderJson(request, response, validateTokenResult, true);
            return;
        }

        // 获取支持的银行列表
        result = bankService.getPayBanks(capitalMode);
        if (result.getSuccess() == false && StringUtil.isEmpty(result.getErrorMessage())) {
            result.setErrorMessage(MessageUtil.getErrorMessage(result.getErrorCode(), null));
        }
        ResponseUtils.renderJson(request, response, result, true);
    }

    /**
     * 获取支付渠道的单笔交易限制
     *
     * @param request
     * @param response
     * @param token
     * @param capitalMode
     * @param bankCode
     * @param deviceId
     * @return
     */
    @RequestMapping(value = "bank-limits", method = RequestMethod.GET)
    @ResponseBody
    @Loggable
    public BaseResult getPayBankLimits(HttpServletRequest request, HttpServletResponse response,
                                       @RequestParam String token, @RequestParam String capitalMode, @RequestParam String bankCode,
                                       @RequestHeader(value = GlobalConstant.HEADER_APP_DEVICE) String deviceId) {
        logger.info("Receive bank-limits request, capitalMode:" + capitalMode);

        // 验证token
        ValidateTokenResult validateTokenResult = userService.validateToken(token, deviceId);
        if (!validateTokenResult.getSuccess()) {
            String errorMessage = MessageUtil.getErrorMessage(validateTokenResult.getErrorCode(), null);
            validateTokenResult.setErrorMessage(errorMessage);
            return validateTokenResult;
        }

        // 获取支持的银行列表
        BaseResult result = bankService.getPayBankLimits(capitalMode, bankCode);
        if (result.getSuccess() == false && StringUtil.isEmpty(result.getErrorMessage())) {
            result.setErrorMessage(MessageUtil.getErrorMessage(result.getErrorCode(), null));
        }

        return result;
    }

}
